﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;

namespace WastedMechanics
{
    public class CharTaskAttack : CharTask
    {
        public Character Who;
        public List<Character> Targets;

        public List<Vector3> Marshroute;
        public Vector3 Target;
        int CurrentPoint;        
        
        public CharTaskAttack(Character chr, Character who, string lbl = "") :
            base(chr, lbl)
        {
            Who = who;
            Targets = new List<Character>(); 
        }

        public override void Begin()
        {
            GetArmed();
        }

        public void GetArmed()
        {
            if (Character.Pistol != null)
            {
                Character.State.HaltOrder();
                Character.TakePistol();
            }
            else if (Character.M1HWeapon != null)
            {
                Character.TakeM1H();
                SetRoute();
            }
        }

        public override void Done()
        {
            Character.State.StopAimingOrder();
            Character.State.HideWeapon();
        }

        public void SetRoute()
        {
            Marshroute = new List<Vector3>();
            Target = Who.Position;
            Engine.CurrentLevel.Navmesh.SearchRoute(Character.Position, Target, Marshroute);
            CurrentPoint = 0;
        }

        public void SortTargetsByDistance()
        {
            Targets.Sort((ch1, ch2) => (ch1.Position - Character.Position).Length.CompareTo((ch2.Position - Character.Position).Length));
        }

        public bool PickNextTarget()
        {
            if (Targets.Count > 0)
            {
                SortTargetsByDistance();
                Who = Targets[0];
                Targets.RemoveAt(0);
                return true;
            }
            else
                return false;
        }
   

        public override void Update()
        {
            if (!IsFinished)
            {
                if (Character.ArmedCase == Character.ArmedCases.M1H)
                {
                    if (Who.IsDead || Who.State.GetType().Name == "CharStateDie")
                    {
                        if (!PickNextTarget())
                        {
                            IsFinished = true;
                            return;
                        }
                    }
                    if (Marshroute.Count == 0)
                    {
                        Console.WriteLine("Heading to closest poly...");
                        Marshroute.Add(Engine.CurrentLevel.Navmesh.FindClosestPolygon(Character.Position).Center);
                        CurrentPoint = 0;
                    }
                    else if (CurrentPoint == Marshroute.Count || ((Character.Position - Who.Position).Length < 1))
                    {

                        Character.State.HaltOrder();
                        Character.TurnTo(Who.Position);
                        Character.M1HHit(Who);

                        if ((Who.Position - Target).Length > 1 || (Character.Position - Who.Position).Length > 1)
                            SetRoute();
                    }
                    else
                    {
                        if (((Character.Position - Marshroute[CurrentPoint]) * new Vector3(1, 0, 1)).Length > 0.3f)
                        {
                            Vector3 turnpoint = Marshroute[CurrentPoint];
                            turnpoint.y = Character.Position.y + Character.Profile.HeadOffset.y;
                            Character.TurnTo(turnpoint);
                            Character.State.MoveOrder(true);

                            if ((Who.Position - Target).Length > 1)
                                SetRoute();
                        }
                        else
                            CurrentPoint++;
                    }
                }
                else if (Character.ArmedCase == Character.ArmedCases.Pistol)
                {
                    Character.TurnTo(Who.Position + Who.Profile.HeadOffset);
                    Character.State.HaltOrder();
                    Character.AimPoint = Who.Position + Who.Profile.HeadOffset * 0.5f;
                    Character.State.AimOrder();
                    Vector3 pistolOrigin = Character.Node.Position + Character.Orientation * new Vector3(-0.15f, 0.65f, 0.1f);

                    Raycaster.PredicateRaycast raycast = new Raycaster.PredicateRaycast(body =>
                        body.UserData != Character
                        && body.UserData != Who
                        && !(body.UserData is GameObject && (body.UserData as GameObject).IsObstacle == false)
                        && !(body.UserData is Character && (body.UserData as Character).IsDead));

                    raycast.Go(Engine.NewtonWorld, pistolOrigin, Who.Position + Who.Profile.HeadOffset);

                    if (raycast.Contacts.Count == 0)
                        Character.Shoot();

                    if (Who.IsDead || Who.State.GetType().Name == "CharStateDie")
                    {
                        if (!PickNextTarget())
                        {
                            IsFinished = true;
                            Character.State.StopAimingOrder();
                        }
                    }
                }
                else
                    GetArmed();
            }            
        }
    }
}
